//
// Created by hunan on 25-7-20.
//

#include "protocol_connection_pool.h"

#include "protocol_connection.h"

ProtocolConnectionPool::ProtocolConnectionPool(Loop * loop)
{
    m_loop = loop;
}

bool ProtocolConnectionPool::InitProtocolConnectionPool(int size, ProtocolOperationFactory * factory)
{
    if (!m_connections.empty())
    {
        return false;
    }
    for (int index = 0; index < size; index++)
    {
        Connection connection   = {};
        connection.m_index      = index;
        connection.m_operate    = factory->CreateProtocolOperation();
        connection.m_connection = std::make_shared<ProtocolConnection>(m_loop, connection.m_operate.get());
        m_connections.push_back(connection);
        m_indexes.push_back(index);
    }
    return true;
}

std::shared_ptr<ProtocolConnection> ProtocolConnectionPool::GetConnection()
{
    std::shared_ptr<ProtocolConnection> result_connection;
    std::unique_lock<std::mutex> lock(m_mutex);
    if (m_indexes.empty())
    {
        return result_connection;
    }
    int index = m_indexes.front();
    m_indexes.erase(m_indexes.begin());
    result_connection = m_connections[index].m_connection;
    return result_connection;
}

void ProtocolConnectionPool::ReleaseConnection(const std::shared_ptr<ProtocolConnection> & connection)
{
    std::unique_lock<std::mutex> lock(m_mutex);
    for (auto & data : m_connections)
    {
        if (data.m_connection.get() == connection.get())
        {
            m_indexes.push_back(data.m_index);
            break;
        }
    }
}

void ProtocolConnectionPool::CloseConnection()
{
    std::unique_lock<std::mutex> lock(m_mutex);
    for (auto & conn : m_connections)
    {
        conn.m_connection->CloseConnection();
    }
    m_connections.clear();
}







